/**
 * @file ShellServer.cpp
 * @author 独霸一方 (2696652257@qq.com)
 * @brief
 * @version 1.0
 * @date 2022-09-18
 *
 * @copyright Copyright (c) 2022
 *
 */

#include "common_inc.h"

/**
 * @brief 必须程序必须保证处于死循环中运行
 *  !这个线程是用于调试用,用于输出信息
 * @param argument
 * @return
 */
void ShellServer(void *argument)
{

    userShellInit_cpp(); //> C++环境初始化shell,除了初始化C环境的shell之外,还初始化了C++中的一些数据结构

    userLogInit_cpp(); //> 初始化log输出,log依托于shell(也可以单独实现)

    HAL_UARTEx_ReceiveToIdle_DMA(&huart1, &(arrayBuffer->_buffer[0]), arrayBuffer->size()); //开启DMA+空闲中断接收,这里之所以可以将buffer的首地址传入是因为etl中array底层实现就是内部维护的一个数组

    for (;;)
    {
        shellTask(&shell);
    }
}

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) //传入的参数就是接收了多少个数据,这个中断函数会被半满,全满,空闲中断调用
{
    if (huart->Instance == USART1)
    {
        HAL_UART_DMAStop(&huart1); //> 关掉DNA是为了下一次重新启用时重新计数

        //为了安全起见,先把第一个数据送入队列先
        fifoArray->push(arrayBuffer->at(0));

        //继续打开接收,从头开始覆盖,这里可能DMA同时与MCU进行读写,但是MCU读写应该还是比DMA(串口速度限制)快的
        HAL_UARTEx_ReceiveToIdle_DMA(&huart1, &(arrayBuffer->_buffer[0]), arrayBuffer->size()); //这里应该重新打开了DMA接收数据,DMA会继续搬送数据

        //! 这里是危险操作,比的就是在两次数据发送中间,CPU抢先于DMA操作缓冲数组
        //> 将数组数据压到FIFO队列中去准备解析,这里DMA跟CPU可能同时进行
        for (int32_t i = 1; i < Size; ++i) //从1开始,0号位置已经被送入队列了
        {
            fifoArray->push(arrayBuffer->at(i));
        }
    }
}
